package com.bay1ts.controller;

import javax.annotation.Resource;

import com.bay1ts.domain.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.bay1ts.service.MailService;
import com.bay1ts.service.UserService;

@Controller
@RequestMapping("/user")
@SessionAttributes({"user","email","phonenumber"})
public class UserController {
	@Autowired
	//@Qualifier("customjdbcUserService")
	private JdbcUserDetailsManager jdbcUserDetailsManager;
	@Autowired
	private UserService userService;
	@Autowired
	private MailService mailService;
	@Resource(name="sessionRegistry")
	private SessionRegistry SessionRegistry;
	

	
	/**
	 * @param user
	 * @param model
	 * @return String
	 * @author Bay1ts 
	 * 修正了接受表单提交过来的数据后，使用明文密码存储的问题。还有问题就是一些默认值的问题，最好在后端校验，现在还没有实现。
	 * 跨controller，使用redirect时，model中数据不会被传递。
	 * 2015-11-11 12:00
	 */
	@RequestMapping("insert")
	public String insert(Users user, Model model){
		userService.insert(user);
		model.addAttribute("user", user);
		return "redirect:/insertsuccess";
	}
	/*
	 *关于下面这几行代码，把一个本会丢失的model中的数据放到了session中，然后立马删除，导致刷新的时候原来在model中的数据会丢失。
	 *这里的modelmap实现比较有特点，请注意一下。请参考这里http://www.dexcoder.com/selfly/article/3955
	 *上面那个实现，基本上是对@modelattribute和@sessionattribute的实践。可以参考一下这里
	 *http://www.cnblogs.com/08shiyan/p/3423384.html
	 *以session为桥梁，一边的@modelattribute(model.add**()也可以)作为输入，另外一边需要这个对象的 @modelattribute作为输出(描述很混乱) 
	 * */
//	@RequestMapping("insert")
//	public String insert(UserDetailsWarpper user,RedirectAttributesModelMap modelmap){
//		String encodedPassword=passwordEncoder.encodePassword(user.getPassword(), saltSource.getSalt(user));
//		user.setPassword(encodedPassword);
//		userService.insert(user);
//		modelmap.addFlashAttribute("user", user);
//		return "redirect:/insertsuccess";
//	}
	
	@RequestMapping("changepassword")
	public String showChangepasswordpage(){
		return "changepassword";
	}
	@RequestMapping(value="changepassword",method=RequestMethod.POST)
	public String submitChangePasswordPage(@RequestParam("oldpassword") String oldpwd,@RequestParam("password") String newpwd){
		jdbcUserDetailsManager.changePassword(oldpwd, newpwd);
		//SecurityContextHolder.clearContext();
		return "redirect:/about";
	}
	
	/**
	 * @return
	 * session里应该有一个yzm对象，在获取验证码时应该生成一个，并且放到session里面，然后在这验证一下。
	 * phonenumber用于在数据库中查询，如果验证成功，还要根据phonenumber.update。
	 */
	@RequestMapping(value="forgot",method=RequestMethod.POST)
	public String forgotpw(String email,Model model){
		//在这里发送邮件，邮件里有个链接，链接上有个随机生成的token。把token要保存到数据库里，数据库里也要有生成token的时间，和token的过期时间。
		//这里返回的页面，要是一个发送成功或者失败的页面，也要包括重新发送的，token和时间记着更新。
		userService.forgetPassword(email);
		model.addAttribute("email", email);
//		model.addAttribute("email", email);
		//设计上的问题：是要留下一个轻量级的controller还是service。上面的做法是保持service层干净，也可以把生成token的工作留给service层。
		//干脆放到dao里面得了.如果用mybatis的话， 好像还放不到dao层里面。
		mailService.sendResetPasswordMail(email);
		//生成token的业务放到service层了。
		return "sended";
	}
	@RequestMapping("confirm")
	public String confirm(@RequestParam(value="code",required=true)String token,ModelMap map){
		//result的解释：1.检验结束，正常，放行。2.链接正确，超时。3.伪造的链接
		int result=userService.confirm(token);
		map.remove("email");
		//下面还可以加一些样式：把结果值分情况加到session里面，把modelmap里面的result attribute remove掉。就能在url没啥区别的情况下将结果分开。当然，也可以带model跳转，就是会在url上追加result信息。
		if(result==1){
			return "redirect:reset";
		}else if(result==2){
			return "redirect:reset?result=timeout";
		}else{
			return "redirect:reset?result=error";
		}
	}
	@RequestMapping(value="reset",method=RequestMethod.GET)
	public String showresetpage(String result,Model model){
		model.addAttribute("result", result);
		return "reset";
	}
	@RequestMapping(value="reset",method=RequestMethod.POST)
	public String resetpassword(@RequestParam(value="pwd",required=true)String pwd,@ModelAttribute("email")String email,ModelMap map){
		//这一句的最后一个参数是email所属用户的userdetails，用于生成salt。
		userService.reset(pwd,email,jdbcUserDetailsManager.loadUserByUsername(userService.getUsernameByEmail(email)));
		map.remove("email");
		//如果没有上面那一句的话，，因为session中存在这个email，所以在redirect时会给加上。这样本是为了解决多个requestmapping之间的跳转，但是url就啰嗦了，所以不需要带model跳转的话，加上这一句就得了
		return "redirect:/login";
	}
	//此项目不支持短信登陆功能
	//@RequestMapping(value="getdynamiclogincode")
//	public String getdynamiclogincode(String phonenumber,ModelMap map){
//		//生成code并按手机号保存到数据库中
//		userService.dynamicLogin(phonenumber);
//		//从数据库中检索出来，发送到指定的手机号上
//		smsService.sendDynamicPasswordMessage(phonenumber);
//		map.addAttribute("phonenumber",phonenumber);
//		//验证码已发送，页面小更新一下，准备接受用户输入的验证码，并提交到/user/confirmDynamicCode?code=******
//		return "redirect:/user/dynamiccodelogin";
//	}
	
//	@RequestMapping("test")
//	@ResponseBody
//	public int test(String u,String p){
//		userService.test(u,p);
//		return 1;
//	}
//	@RequestMapping("dynamiccodelogin")
//	public String showdynamicloginpage(){
//		List l=SessionRegistry.getAllPrincipals();
//		for(Object o:l){
//			System.out.println(o.toString());
//		}
//		return "dynamiccodelogin";
//	}
//	@RequestMapping(value = "dynamiccodelogin",method = RequestMethod.POST)
//	public String dynamiclogin(String code,ModelMap map){
//		return "";
//	}


}
